﻿// ***********************************************************************
// Assembly         : STX.Service
// Author           : seven.x
// Created          : 12-26-2013
//
// Last Modified By : seven.x
// Last Modified On : 01-06-2014
// ***********************************************************************
// <copyright file="BaseService.cs" company="驰创数码">
//     Copyright (c) 驰创数码. All rights reserved.
// </copyright>
// <summary></summary>
// ***********************************************************************
using System;
using System.Linq;
using STX.Lib.Caching;
using STX.Domain;
using STX.Repository;
using STX.Service.Valid;

namespace STX.Service
{
    /// <summary>
    /// Class BaseService.
    /// </summary>
    /// <typeparam name="TEntity">The type of the attribute entity.</typeparam>
    public abstract class BaseService<TEntity>
        where TEntity : BaseEntity
    {
        #region Properties
        /// <summary>
        /// Gets or sets the cache provider.
        /// </summary>
        /// <value>The cache provider.</value>
        public ICacheProvider CacheProvider { get; set; }


        /// <summary>
        /// Gets or sets the transaction.
        /// </summary>
        /// <value>The transaction.</value>
        public ITransactionContext Transaction { get; set; }

        #endregion

        #region Methods

        #region Method 添加记录
        /// <summary>
        /// Adds the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <param name="successAction">The success action.</param>
        /// <returns>System.Int64.</returns>
        public virtual long Add(TEntity entity, Action<ITransactionContext, TEntity> successAction = null)
        {
            var repository = Transaction.GetRepository<TEntity>();
            repository.Add(entity);
            Transaction.Commit();
            if (entity.Id > 0 && successAction != null)
                successAction(Transaction, entity);
            return entity.Id;
        }

        #endregion 

        #region Method 更新记录
        /// <summary>
        /// 更新记录（注意，entity 必须位于ef context中。）
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public virtual bool Update(TEntity entity)
        {
            Transaction.Commit();
            return true;
        }

        #endregion

        #region Method 查询记录
        /// <summary>
        /// Finds all.
        /// </summary>
        /// <param name="exp">The exp.</param>
        /// <returns>IQueryable{`0}.</returns>
        public virtual IQueryable<TEntity> FindAll(Func<TEntity, bool> exp)
        {
            var repository = Transaction.GetRepository<TEntity>();
            return repository.FindAll(exp);

        }


        public virtual IQueryable<TEntity> FindAll(string sql, params object[] parameters)
        {
            var repository = Transaction.GetRepository<TEntity>();
            return repository.FindAll(sql, parameters);

        }

        /// <summary>
        /// Finds all.
        /// </summary>
        /// <returns>IQueryable{`0}.</returns>
        public virtual IQueryable<TEntity> FindAll()
        {
            var repository = Transaction.GetRepository<TEntity>();
            return repository.FindAll();
        }

        /// <summary>
        /// Finds the model by unique identifier.
        /// </summary>
        /// <param name="id">The unique identifier.</param>
        /// <returns>`0.</returns>
        public virtual TEntity FindModelById(int id)
        {
            var repository = Transaction.GetRepository<TEntity>();
            return repository.FindAll().FirstOrDefault(o => o.Id == id);
        }

        #endregion

        #region Method 删除记录

        /// <summary>
        /// Removes the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public virtual bool Remove(TEntity entity)
        {
            var repository = Transaction.GetRepository<TEntity>();
            var model = repository.FindAll().FirstOrDefault(o => o.Id == entity.Id);
            if (model != null)
            {
                repository.Remove(model);
                Transaction.Commit();
            }
            return Transaction.AffectedRows > 0;
        }

        /// <summary>
        /// Removes the ids.
        /// </summary>
        /// <param name="ids">The ids.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public virtual bool RemoveIds(int[] ids)
        {
            var repository = Transaction.GetRepository<TEntity>();
            repository.RemoveIds(ids);
            Transaction.Commit();
            return Transaction.AffectedRows > 0;
        }

        #endregion

        /// <summary>
        /// Valids the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <param name="validExpression">The valid expression.</param>
        /// <exception cref="System.Exception"></exception>
        public void Valid(TEntity entity, IValidExpression<TEntity> validExpression)
        {
            var result = validExpression.Valid(entity);
            if (result.IsValida) return;
            throw new Exception(result.Summry);
        }

        #endregion
    }
}
